package jdesktop.appbar;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.awt.*;

public class DefaultAppBarModel implements AppBarModel
{

    /**
     * The edges that this appbar can be docked to.
     * @see #ALLOWEDEDGES
     */
    private final Sides   allowedEdges = new Sides().setAll(true);

    /**
     * The edge of the screen this appbar occupies. Default value is {@value}.
     * @see #EDGE
     */
    private Edge edge = Edge.LEFT;

    /**
     * The size of the bar. This is size of the dimension that is parallel to the orientation
     * of the bar. For a bar along the top/bottom edge, it is the heigh of the bar, for a bar
     * along the left/right edge, it is the width of the bar.)
     * <p>
     * This value can be set explicitly via {@link #setBarSize} or implicitly when the window
     * is resized.
     * @see #setBarSize
     * @see #getBarSize
     */
    private int barSize = DEFAULT_BARSIZE;

    /**
     * The last explicitly set barsize.
     * @see #barSize
     */
    private int desiredBarSize = DEFAULT_BARSIZE;

    /**
     * Manually specified hidden state of insets.
     * @see #OVERRIDEHIDEINSETS
     */
    private final Sides overrideHideInsets = new Sides(true);

    /**
     * Defines which insets to auto-hide.
     * @see #AUTOHIDEINSETS
     */
    private final Sides autoHideInsets = new Sides(true);

    /**
     * The insets auto-hide state.
     */
    private final Sides autoHiddenInsets = new Sides(false);

    /**
     * The final state for whether or not an inset is hidden.
     */
    private final Sides insetsHideState = new Sides(false);

    /**
     * When an inset is hidden, normally the ensire inset is hidden. This property
     * allows part of the insets to be revealed. This mimics the taskbar in Windows, which
     * displays 2px of the inset. Naturally, this is very dependent upon the styling and
     * version of windows..
     * The default {@code insetReveal} value of zero for an inset hides
     * the entire inset when it is flagged as hidden.
     * A Positive value
     * reveals a corresponding number of pixels of the inset from the inside edge.
     * A negative value reveals from the outside edge. Setting a value whose magnitude is
     * greater than the corresponding inset reveals the entire inset.
     */
    private final Insets insetsReveal = new Insets(0,0,0,0);

    /**
     * The {@link #DOCKED} property.
     */
    private boolean docked      = true;

    private final PropertyChangeSupport   pcs;

    private double autoHideAmount;

    public DefaultAppBarModel()
    {
        pcs = new PropertyChangeSupport(this);
    }

    public Edge getEdge()
    {
        return edge;
    }

    public void setEdge(Edge edge)
    {
        Edge old = this.edge;
        this.edge = edge;
        if (old!=edge)
            pcs.firePropertyChange(EDGE, old, edge);
    }

    public int getBarSize()
    {
        return barSize;
    }

    public void setBarSize(int barSize)
    {
        int old = this.barSize;
        this.barSize = barSize;
        if (old!=barSize)
            pcs.firePropertyChange(BARSIZE, old, barSize);
    }

    public int getDesiredBarSize()
    {
        return desiredBarSize;
    }

    public void setDesiredBarSize(int desiredBarSize)
    {
        int old = this.desiredBarSize;
        this.desiredBarSize= desiredBarSize;
        if (old!=desiredBarSize)
            pcs.firePropertyChange(DESIREDBARSIZE, old, desiredBarSize);
    }

    public boolean isDocked()
    {
        return docked;
    }

    public void setDocked(boolean docked)
    {
        boolean old = this.docked;
        this.docked = docked;
        if (old!=docked)
            pcs.firePropertyChange(DOCKED, old, docked);
    }

    // todo - finish these methods
    public Sides getAllowedEdges()
    {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public boolean isResizable()
    {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public boolean isFloatable()
    {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public Rectangle getFloatableRectangle()
    {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public void getFloatBounds(Rectangle current)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public boolean setFreezeNotification(boolean freeze)
    {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void addPropertyChangeListener(PropertyChangeListener listener)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void removePropertyChangeListener(PropertyChangeListener listener)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void setFloating(boolean floating)
    {
        setDocked(!floating);
    }

    public void setFloatingLocation(int x, int y)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void setFloatingSize(int width, int height)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public double getAutoHideAmount()
    {
        return autoHideAmount;
    }

    public void setAutoHideAmount(double autoHideAmount)
    {
        this.autoHideAmount = autoHideAmount;
    }
}
